home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-08-29 | 12.5 KB | 244 lines | [TEXT/edF6] |
- In the unregistered version of PowerFantasm, source code for this is not included for
- two reasons.
- 1. The demo can't assemble it because of a code size limitation, and
- 2. We have to keep the unregistered version size down to a minimum.
-
- ----------------------------------------------------------------------------------
-
- PF410 was to be released with no new example code. Then a few days back I was given
- a challenge. These are the notes from that challenge.
-
- The challenge was to write the basics of a native sprite based game in 24 hours and this
- is the result.
-
- It starts off 7 hours in, as the first seven hours were writing the basic screen splat
- and routines.
-
- Big note for splats - a read or write
- to memory with the floating double instructions will cause a memory exception on
- 604's, so make sure you are 8 aligned if using these instructions - see the screen
- splat and init code for usage...
-
- Another note - in this particular example the MMU was letting me get away with passing a
- really bad address to clear_icl8 until I switched VM on - then the machine crashed.
- Be very sure to check both with VM on and off as the MMU behaves differently.
-
- -------------------------------------------------------------------------------
-
- Ok, 7 hours in and I'm working on the player bullets. Have defined four arrays,
- each 10 halfs each. x,y,old_x and old_y for each bullet.
- The theory is that when we press the mouse button, the y_array is searched for an empty slot
- - that is any slot containing -1. We store x and y coords of the left gun in these arrays.
- Calc_bullets steps through the y array looking for entries that are not -1. These are
- valid y coords. The y coord is decremented by 10, then checked against 20.
- If greater than 20 then do the next bullet slot. If less than 20 then delete the bullet
- and set this y_coord to -1.
-
- This set up limits the number of player bullets on screen to 10 (in the equates file).
- Because the gun will
- auto repeat, after firing a bullet we set a delay so that the fire routine isn't checked
- again until this counter runs out.
-
- Next, get it to fire two bullets at the same time - one from each gun. I think that this is
- simply a case of altering the coords when we fire and saving it in the next x and y
- slot.
-
- Well, aparently not! The first bullet comes out of the left hand gun as it should, but the
- other comes out of the bottom of the screen displaced left by some 200 pixels! Eh?
-
- Turns out to just have been bad maths - however, I did think it be a good idea to have the
- guns alternate, left/right so reduced the fire delay to 4 cycles and introduced a variable - turret?
- which makes the routine alternate left/right guns (which will make for better sound!)
-
- Ok, now I've added an equates file to the project, and redefined the number of bullets to
- 20. I noticed that the bullets routines were not working right, in that after the max number
- had been fired, the guns would not fire until the last bullet cleared the screen. This
- was traced to the compare to -1 conditional branch in find_slot being the wrong way
- round - should've been a beq!
-
- Noticed that the players ship is slightly blanking out the bullets in the first frame of
- bullet movement on the right hand size. This is because I'm simply clearing the whole
- 32 bits width befoire drawing a bullet, when in fact I only need to clear the bullet width
- which is three. So, by moving the bullet over to the far left of the icl8 and
- changing clear and print icl8_little, I'll gain speed and remove the visual interference.
-
- Ok, so modified both clear and print - what I did to make sure it was working properly was
- change the background colour of the bullet from zero to 1, so I could see how much was being
- printed. Also the sprite has been reduced to three pixels wide as it looks better, and
- the print adjusted accordingly
-
- Ok, it's midnight, which is 8 hours in. The players bullets are now finished.
-
- Now, onto the nasties. I have to decide on the maximum on screen any any one time.
-
- For now I'll say 20. Each monster is one single icl8, so we need 4 arrays again,
- x,y,old_x and old_y - each sized to number_monsters.
-
- We need three routines. One to init the positions. One to calculate positions, and one to
- draw the little blighters (erasing the old ones first obviously) It's important, as the
- monsters can cross each other, to erase all of them in one go.
-
- To be honest, at this stage, I'll be happy just to draw them and get a frame timing, then
- adjust the maximum number accordingly.
-
- So, first to init monsters. As this is a simple game, for now I'm just using one monster
- shape - icl8 140. Read into monster_sprite1
- I'm going to use fixed data, in init to initialise the arrays. Because i~ have to
- type in the data, for now I've set the number of monsters to 5. The init routine
- simply copies the x and y coords out of the data to the x,y,x_old and y_old arrays.
-
- Get some coffee.
-
- Ok, it 0025 now, and the init routine is done. Next draw_monsters. First this has to
- go through the arrays and call blank_icl8 which will erase all the old monsters.
- Then again, go through a loop, anloy this time call draw_icl8 which is already written.
-
- Ok, I've written the clear and splat routines for the monsters, now before running them
- I need to get a timing for 1000 frames then I can see how much the monster print has slowed
- it down.
- Without the stars or monsters I get 532 ticks, which is 1000/(532/60) 113 frames/sec.
-
- Now switch on the monster print...and...589 ticks - thats with 5 monsters=101 fps.
- However, what the monster print routine is printing isn't how it looks in Resedit!
- So, hello Macsbug...As it turns out, didn't need Macsbug, it's just that splat_icl8
- doens't preserve the pointer to the data, so I just saved it in r25 and all is ok.
- BUT I did notice that the splat_icl8_three_vert routine seems to be splatting 64
- rather than 32 bytes horizontally...yup, it was the clear routines rather than the
- splat routines - a hangover from the integer unit word splat.
-
- SO, finally, I can get a time with the stars and five monsters - 102 fps.
- Now lets bung up the number of monsters to 10 - 93 fps, now lets see if I cant get
- that up by 1. Apparently not at this stage. OK. Well it's 0100, so thats 9 hours.
-
- Next up is the monster movement routines. As I only have 15 hours left, it's has to be
- simple this time. I think first I'll write a default controller which just flaots
- the monsters about - if they hit a side, then reverse the delta in that direction.
-
- So, we need two more arrays - mdelta_x and mdelta_y (as bytes) BUT at this time, I know
- that I'm going to use more than one control mechanism, so I'll define another array
- (of bytes) - mcontrol.
-
- In the init phase, we generate random delta values for the monsters - minimum of 1 and
- maximum of 3, but this isn't called in the normal init, as we want to call this routine
- to start a new stage, so I'll define a new source file - wave_init.s
- Ok, written a routine -wave_init which sets up the arrays with random delta values,
- in the range of 0-3. This means it's possible to get monsters that wont move, but I'll
- sort that out later. (add 1 if zero etc)
-
- Next routine is move_monsters. This gets each monsters x,y and delta_x,y.
- Checks the coords of each monster, and if out of bounds, reverses the relevant
- delta. Took twenty minutes to write and now the game crashes brilliantly!
-
- Hmm, ok, this was a classic mistake. The x and y's are half sized arrays, the deltas
- are bytes - I was simply adding just 1 to the x and y array pointers, so the first x was
- correct, all the rest were rubbish! Now, all the monsters are simply moving to the
- corners and staying there, which would really make the game too easy :-)
-
- Coffee...
-
- Ok, two faults. Firstly I wasn't saving the delta values back in the array, and
- secondly because we are using signed delta values, I needed to extend the sign of
- the delta byte! Ok, so it now works! As predicted one of the monsters didn't move
- so back into wave init... It turns out that monster #10 is not moving?
- Into Macsbug, check out the delta arrays and sure enough, entry 10 is 0?
- Bummer - wave_init was stuffing both deltas into the same array! Fixed now and all my
- little aliens are moving - hurrah!
-
- Lets get a frame rate...94fps.
-
- Phew. Right is 1:45, which means this is nearly 10 hours in so far.
-
- Next up is player bullets hitting the nasty aliens. Now when an alien is hit, all we
- have to do is set its y coord to -1 and modify the routines to ignore such a beasty.
-
- First though, we need to go back into calc_bullets to detect a hit. In calc_b_loop
- we subtract 10 from the bullets y coord. Given this coord we can call check_monster_hit
- which compares the bullets x and y coords with all active aliens. If the bullet is in one
- of the aliens rectangles, it returns the monster number, otherwise zero. This is less
- tidy than calling a routine from the main loop, but is faster as we have the bullets coords
- and number handy.
-
- Time for some music, as this will take a while to write - eh? This disk is unreadable by...
- Oh yes, best put the foreign file access thingies in...
-
- Ok, routines written, and it don't crash, but it isn't working, so I;m going to reduce the
- number of monsters to 1 so it's easier to debug.
-
- Doddle - just a mix up over x and y's. In check_monster_hit, if it is, all we do is
- bung a -1 in the monsters y coord and it goes away. Right bung the number of monsters
- back upto 20 and give it a blast (ah the joys of equate files).
-
-
- Ok, something very weird is happening. As I shoot monsters, then game gets slower and
- slower? I'm supposed to be equalising now! Yup, I had forgotten to modify the drawing routines
- to take account of y values with -1. The reason it was slowing down is because it was
- drawing off screen, which is probably not lined up on an 8 byte boundary! Anyway, I've
- added a down counter that decrements when a monster is killed, and when zero sets the
- global flag end_of_wave to tell the main loop to stop.
-
- Phew. 0300 and looking good. Right lets get a frame check with 10 monsters - 92.7 fps.
- And with 20..remembering to make some more entries in the init data...80 fps. So we're
- still good for a few number of aliens.
-
- Now, next we come to the aliens dropping bombs on us - we need some rules first.
- One alien - one bomb. Now because these monsters have to decide when to drop a bomb,
- we do not want to be calling get_random for every monster in every loop - far too slow.
- What I'll do is define two more arrays - monster_bomb_counter and monster_bomb_counter_reset.
- These are set up in wave_init and when the counter reaches zero, the monster tries
- to drop a bomb. If it has no active bomb then it can drop one. We reset the counter
- from the reset array. This way, all we have to do is decrement a counter - far faster.
-
- An inactive bomb is indicated by -1 in the monster_bomb_y array.
-
- Right, lets do it...First off, wave_init to set up the counter arrays. Ok minor change,
- another array - monster_bomb_deltas - the y delta for the bomb - set in init_wave.
- Ok, after an hour and half of mucking about tweaking things, that now works. Main problem
- was making sure dead aliens don't drop bombs!
-
- Next is the player/alien bomb collision detection. This fits naturally into the move monster
- nomb routine at label check_player.
-
- Finally is alien/player collision - again same stuff - draw a rectangle and compare, but
- this time we have to check all four corners of the monster against the players rectangle.
- Done in draw_m_loop.
-
- OK, its 0630 - fps check.
- 20 monsters - 80 frames/sec
- 10 monsters - 93 fps. Dont seem to have wasted any time on the collision detection. Good.
-
- Now it's time to add some basic levels - simple:
- Level 1=5 monsters
- level 2=10
- level 3=15
- level 4=20
- Then bonus level which ends scheme 1.
- ...
- So some four hours later, I've added in basic sound, some very simple level increments
- and got our artist to draw some simple sprites - the end result you can see for yourself!
-
- ----------------------------------------------------
-
- Endispiece...
-
- Well, all that was done about three or four days ago. I have now recovered :-)
-
- I'd like to thank Rob, Claire and James for support.
- Not only for this little demo, but for all the stirling work they do otherwise.
-
-
-
- Please note that:
- 1. All code contained in PF410 example game is copyright Lightsoft 96.
-
- 2. Some of the clear and splat routines can be optimised further - for example
- you may find the odd li instruction in a loop, which can move outside etc.
-
- Feel free to use the ideas contained herein, but please do not simply push this work out
- as your own. If you use portions of the game code in your own games, then you are
- legally obliged to state that portions of the code are copyright Lightsoft.
-
- Thankyou.
-
-
- -----------------------------------
-